#include <iostream>
#include <cstring>

template <typename Item>
class Array;

template <typename Item>
std::ostream &operator<<(std::ostream &os, const Array<Item> &arr)
{
    for (int idx = 0; idx < arr.m_size; idx++)
    {
        os << arr.m_data[idx] << std::endl;
    }
    return os;
}

template <typename Item>
class Array
{
public:
    friend std::ostream &operator<< <>(std::ostream &os, const Array<Item> &arr);

private:
    Item *m_data;
    int m_size;
    int m_capacity;
    const int default_size = 10;

private:
    bool checkIndex(int index);

public:
    Array() : Array(10) {}
    Array(int capacity)
    {
        if (capacity <= 0)
        {
            capacity = default_size;
        }
        m_data = new Item[capacity];
        if (m_data == nullptr)
        {
            throw "new error";
        }
        memset(m_data, 0, sizeof(Item) * capacity);
        m_capacity = capacity;
        m_size = 0;
    }
    ~Array()
    {
        if (m_data)
        {
            delete[] m_data;
            m_data = nullptr;
        }
    }

public:
    bool add(Item value);
    void insert(int index, Item value);
    Item get(int index);
    Item &operator[](int index);
};

template <typename Item>
bool Array<Item>::checkIndex(int index)
{
    return !(index < 0 || index >= m_size);
}

template <typename Item>
bool Array<Item>::add(Item value)
{
    if (this->m_size == m_capacity)
    {
        /*扩容*/
    }
    m_data[m_size++] = value;
    return true;
}

template <typename Item>
Item Array<Item>::get(int index)
{
    if (checkIndex(index))
    {
        return m_data[index];
    }

    return nullptr;
}

template <typename Item>
Item &Array<Item>::operator[](int index)
{
    return m_data[index];
}


int main()
{
    Array<int> array;
    array.add(12);
    array.add(3);
    array.add(21);
    // std::cout << array;
    std::cout << array[0] << std::endl;
    std::cout << array[1] << std::endl;
    return 0;
}
